package com.cebbank.yyi.springbootapp.filter.extend;

import com.cebbank.yyi.springbootapp.exception.CustomException;
import com.cebbank.yyi.springbootapp.filter.SqlMappersFilter;
import com.cebbank.yyi.springbootapp.filter.SqlMapperFilterChain;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.plugin.Invocation;

import java.lang.reflect.InvocationTargetException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @description: 删出表的禁止！
 * @author: yyi
 * @version: 1.0
 **/
public class DefaultSqlMapper implements SqlMappersFilter {

    private final Set<String> forbiddenSqlPatterns = new HashSet<>();

    public DefaultSqlMapper() {
        forbiddenSqlPatterns.add("DROP TABLE.*");
    }

    @Override
    public Object doFilter(Invocation invocation, SqlMapperFilterChain sqlMapperFilterChain) throws InvocationTargetException, IllegalAccessException {
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        String sql = statementHandler.getBoundSql().getSql();
        List<ParameterMapping> parameterMappings = statementHandler.getBoundSql().getParameterMappings();
        //当parameterMappings为0的时候 代表为传入的sql 需要校验，否则为mybatis中传入的sql
        sql = sql.replaceAll("\\s+", " ");
        //System.err.println("输出当前执行的sql:" + sql);
        //判断当前sql是否合法
        if (parameterMappings.isEmpty()) {
            for (String pattern : forbiddenSqlPatterns) {
                Pattern patterns = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
                Matcher matcher = patterns.matcher(sql);
                if (matcher.find()) {
                    throw new CustomException("Forbidden SQL statement detected: " + sql);
                }
            }
        }
        return sqlMapperFilterChain.doFilter(invocation);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
